import jobService, { type PageListReq } from "@/api/services/tool/jobService";
import { TableToolbar } from "@/components/grid/TableToolbar";
import useDictionary from "@/hooks/system/useDictionary";
import { t } from "@/locales/i18n";
import { ClockCircleOutlined, UnorderedListOutlined } from "@ant-design/icons";
import { Button, Card, Drawer, Form, Input, Modal, Radio, Select, Space, Switch, Tag } from "antd";
import Table, { type ColumnsType } from "antd/es/table";
import { useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner";
import CronGenerator from "./CronGenerator";
import type { Job } from "./entity";
import JobLogPage from "./jobLog";
const { TextArea } = Input;

export default function JobPage() {
	const [loading, setLoading] = useState(false);
	const [queryParams, setQueryParams] = useState<PageListReq>({
		jobName: undefined,
		jobGroup: undefined,
		page: 1,
		pageSize: 10,
	});
	const [total, setTotal] = useState(0);
	const [list, setList] = useState<Job[]>([]);
	const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
	const [tableSize, setTableSize] = useState<"large" | "middle" | "small">("middle");
	const [drawerVisible, setDrawerVisible] = useState(false);
	const [editingData, setEditingData] = useState<Job | null>(null);
	const [form] = Form.useForm();
	const [isView, setIsView] = useState(true);

	const [expressionVisiable, setExpressionVisiable] = useState(false);

	const [logVisiable, setLogVisiable] = useState(false);

	//动态设置表格高度
	const [tableScrollY, setTableScrollY] = useState(0);
	const PAGE_OFFSET_HEIGHT = 403;
	const updateTableHeight = () => {
		const newHeight = window.innerHeight - PAGE_OFFSET_HEIGHT;
		setTableScrollY(newHeight > 200 ? newHeight : 200); // 保证最小高度
	};
	useEffect(() => {
		updateTableHeight(); // 初始化
		window.addEventListener("resize", updateTableHeight);
		return () => window.removeEventListener("resize", updateTableHeight);
	}, []);

	const concurrentOptions = useDictionary("system_true_false");
	const statusOptions = useDictionary("system_status");

	const columns: ColumnsType<Job> = [
		{
			title: "任务名称",
			width: 120,
			key: "jobName",
			dataIndex: "jobName",
		},
		{
			title: "任务组名",
			width: 120,
			key: "jobGroup",
			dataIndex: "jobGroup",
			render: (_, record) => <>{record.jobGroup === "default" ? "默认" : "系统"}</>,
		},
		{
			title: "调用目标字符串",
			width: 120,
			key: "invokeTarget",
			dataIndex: "invokeTarget",
		},
		{
			title: "cron执行表达式",
			width: 120,
			key: "cronExpression",
			dataIndex: "cronExpression",
		},
		{
			title: "状态",
			width: 120,
			key: "status",
			dataIndex: "status",
			render: (_, record) => (
				<Switch
					checkedChildren="开启"
					unCheckedChildren="关闭"
					checked={record.status === "1"}
					onChange={(checked) => {
						const newStatus = checked ? '1' : '0';
						const data:Job = {
							...record,
							status: newStatus
						}
						// 调用你的更新函数，例如
						handleStatusChange(data);
					}}
				/>
			),
		},
		{
			title: "备注信息",
			width: 120,
			key: "remark",
			dataIndex: "remark",
		},
		{
			title: "操作",
			fixed: "right",
			key: "operation",
			align: "center",
			width: 100,
			render: (_, record) => (
				<Space>
					<Button type="link" onClick={() => handleView(record)}>
						{t("common.view")}
					</Button>
					<Button type="link" onClick={() => handleEdit(record)}>
						{t("common.edit")}
					</Button>
					<Button type="link" onClick={() => handleRun(record)}>
						执行一次
					</Button>
					<Button type="link" onClick={() => handleLog(record)}>
						日志
					</Button>
				</Space>
			),
		},
	];

	const [selectedValues, setSelectedValues] = useState<string[]>(() =>
		columns.filter((col) => col.key !== "operation").map((col) => String(col.key!)),
	);

	const filteredColumns = useMemo(() => {
		return [...columns.filter((col) => selectedValues.includes(String(col.key)) || col.key === "operation")].sort(
			(a, b) => {
				const originalIndex = columns.findIndex((c) => c.key === a.key);
				const targetIndex = columns.findIndex((c) => c.key === b.key);
				return originalIndex - targetIndex;
			},
		);
	}, [selectedValues]);

	//加载表格数据
	const fetchPageList = () => {
		setLoading(true);
		jobService
			.pageList(queryParams)
			.then((res) => {
				setList(res.records);
				setTotal(res.total);
			})
			.catch((error) => {
				console.log(error);
				toast.error("获取数据失败！", error);
			})
			.finally(() => {
				setLoading(false);
			});
	};

	useEffect(() => {
		fetchPageList();
	}, [queryParams]);

	//选择其他页
	const handlePageChange = (newPage: number, newPageSize: number) => {
		setQueryParams((prev) => ({
			...prev,
			page: newPage,
			pageSize: newPageSize,
		}));
	};

	//触发编辑按钮
	const handleEdit = (job: Job) => {
		setEditingData(job);
		form.setFieldsValue(job);
		setDrawerVisible(true);
		setIsView(false);
	};

	const handleStatusChange = async (job: Job) => {
		await jobService.changeStatus(job).then(res => {
			toast.success("修改成功");
			fetchPageList();
		}).catch(error => {
			toast.error(error.message);
		})
	}

	//触发视图按钮
	const handleView = (job: Job) => {
		setEditingData(job);
		form.setFieldsValue(job);
		setIsView(true);
		setDrawerVisible(true);
	};

	//执行定时任务
	const handleRun = async (job: Job) => {
		setLoading(true);
		await jobService
			.runJob(job)
			.then((res) => {
				toast.info("执行成功！");
			})
			.catch((error) => {
				toast.error(`执行失败！${error.message}`);
			})
			.finally(() => {
				setLoading(false);
			});
	};

	const handleLog = (job?: Job) => {
		if (job) {
			setEditingData(job);
		}
		setLogVisiable(true);
	};

	const logColse = () => {
		setLogVisiable(false);
		setEditingData(null);
	};

	//提交表单数据
	const handleSubmit = async (values) => {
		try {
			setLoading(true);
			if (editingData) {
				await jobService.update({ ...values, id: editingData.id });
				toast.success("更新定时任务调度成功");
			} else {
				await jobService.add(values);
				toast.success("创建定时任务调度成功");
			}
			setDrawerVisible(false);
			setEditingData(null);
			form.resetFields();
			fetchPageList();
		} catch (error) {
			toast.error(`${error.message}`);
		} finally {
			setLoading(false);
		}
	};

	const handleDrawerClose = () => {
		setDrawerVisible(false);
		setEditingData(null);
		form.resetFields();
	};

	const handleAdd = () => {
		setEditingData(null);
		form.resetFields();
		setDrawerVisible(true);
		setIsView(false);
	};

	const handleDelete = async () => {
		try {
			setLoading(true);
			await jobService.remove(selectedRowKeys);
			toast.success("删除定时任务调度成功");
			setSelectedRowKeys([]);
			fetchPageList();
		} catch (error) {
			toast.error(`删除失败: ${error.message}`);
		} finally {
			setLoading(false);
		}
	};

	//打开cron表达式组件
	const showExpression = () => {
		setExpressionVisiable(true);
	};

	const handleExpressionOk = () => {
		console.log("当前表达式:", form.getFieldValue("cronExpression"));

		setExpressionVisiable(false); // 关闭 Drawer
	};

	return (
		<>
			<Card className="mb-4">
				<Form
					layout="inline"
					onFinish={(values) => {
						setQueryParams((prev) => ({
							...prev,
							...values,
							page: 1,
						}));
					}}
				>
					<Form.Item name="jobName" label="任务名称">
						<Input placeholder="请输入任务名称" allowClear />
					</Form.Item>
					<Form.Item name="jobGroup" label="任务组名">
						<Input placeholder="请输入任务组名" allowClear />
					</Form.Item>
					<Form.Item>
						<Button type="primary" htmlType="submit">
							查询
						</Button>
						<Button
							className="ml-2"
							onClick={() => {
								setQueryParams({ page: 1, pageSize: 10 });
							}}
						>
							重置
						</Button>
					</Form.Item>
				</Form>
			</Card>
			<div className="h-4" />
			<Card>
				<div className="flex justify-between mb-4">
					<div className="flex gap-2">
						<Button type="primary" onClick={handleAdd}>
							新增
						</Button>
						<Button danger disabled={selectedRowKeys.length === 0} onClick={handleDelete}>
							删除
						</Button>
						<Button icon={<UnorderedListOutlined />} onClick={() => handleLog()}>
							日志
						</Button>
					</div>
					<TableToolbar
						onRefresh={() => setQueryParams((prev) => ({ ...prev }))}
						onSizeChange={setTableSize}
						columns={columns}
						selectedValues={selectedValues}
						onColumnChange={setSelectedValues}
					/>
				</div>
				<Table
					rowKey="id"
					size={tableSize}
					scroll={{ y: tableScrollY, x: "max-content" }}
					loading={loading}
					pagination={{
						total,
						current: queryParams.page,
						pageSize: queryParams.pageSize,
						onChange: handlePageChange,
					}}
					columns={filteredColumns}
					dataSource={list}
					rowSelection={{
						type: "checkbox",
						selectedRowKeys: selectedRowKeys,
						onChange: (selectedKeys) => {
							setSelectedRowKeys(selectedKeys as string[]);
						},
					}}
				/>
			</Card>

			<Form form={form} labelCol={{ span: 6 }} wrapperCol={{ span: 18 }} onFinish={handleSubmit} disabled={isView}>
				{/* 编辑表单 */}
				<Drawer
					title={editingData ? "编辑定时任务调度" : "新增定时任务调度"}
					width={480}
					open={drawerVisible}
					onClose={handleDrawerClose}
					footer={
						<div className="flex justify-end gap-2">
							<Button onClick={handleDrawerClose}>取消</Button>
							{!isView && (
								<Button type="primary" onClick={() => form.submit()}>
									确定
								</Button>
							)}
						</div>
					}
				>
					<Form.Item
						name="jobName"
						label="任务名称"
						rules={[
							{
								required: true,
								message: "请填写任务名称",
							},
						]}
					>
						<Input placeholder="请输入任务名称" allowClear />
					</Form.Item>
					<Form.Item name="jobGroup" label="任务组名">
						<Select
							options={[
								{ value: "default", label: "默认" },
								{ value: "system", label: "系统" },
							]}
							allowClear
							defaultValue="default"
						/>
					</Form.Item>
					<Form.Item name="invokeTarget" label="调用目标字符串">
						<Input placeholder="请输入调用目标字符串" allowClear />
					</Form.Item>
					<Form.Item label="cron执行表达式" required>
						<Input.Group compact style={{ width: "100%" }}>
							<Form.Item
								name="cronExpression"
								noStyle
								rules={[
									{
										required: true,
										message: "请填写或生成 Cron 表达式",
									},
									{
										pattern: /^(\S+\s+){5,6}\S+$/,
										message: "表达式格式错误，应为6~7段 Cron 表达式",
									},
								]}
							>
								<Input style={{ width: "calc(100% - 120px)" }} placeholder="请输入cron表达式" />
							</Form.Item>
							<Button style={{ width: "120px" }} icon={<ClockCircleOutlined />} onClick={showExpression}>
								生成表达式
							</Button>
						</Input.Group>
					</Form.Item>
					<Form.Item name="misfirePolicy" label="计划策略">
						<Radio.Group
							block
							options={[
								{ label: "立即执行", value: "1" },
								{ label: "执行一次", value: "2" },
								{ label: "放弃执行", value: "3" },
							]}
							defaultValue="3"
							optionType="button"
							buttonStyle="solid"
						/>
					</Form.Item>
					<Form.Item name="concurrent" label="是否并发">
						<Radio.Group block options={concurrentOptions} defaultValue="1" optionType="button" buttonStyle="solid" />
					</Form.Item>
					<Form.Item name="status" label="状态">
						<Select options={statusOptions} allowClear />
					</Form.Item>
					<Form.Item name="remark" label="备注信息">
						<TextArea />
					</Form.Item>
				</Drawer>

				<Drawer
					title="Cron表达式生成器"
					width={400}
					open={expressionVisiable}
					onClose={() => setExpressionVisiable(false)}
					footer={
						<div className="flex justify-end gap-2">
							<Button onClick={() => setExpressionVisiable(false)}>取消</Button>
							<Button type="primary" onClick={handleExpressionOk}>
								确定
							</Button>
						</div>
					}
				>
					<CronGenerator
						value={form.getFieldValue("cronExpression")}
						onChange={(val) => form.setFieldValue("cronExpression", val)}
					/>
				</Drawer>
			</Form>

			<Modal
				title="调度日志"
				open={logVisiable}
				width="100%"
				style={{ top: 0, maxWidth: "98vw", padding: 10 }}
				styles={{
					body: { height: "calc(100vh - 200px)", overflow: "auto", padding: "10px 24px" },
					content: { maxWidth: "100vw", overflow: "hidden" },
					header: { padding: "16px 24px" },
					footer: { padding: "10px 24px" },
				}}
				onCancel={logColse}
				footer={
					<div className="flex justify-end gap-2">
						<Button onClick={logColse}>取消</Button>
					</div>
				}
			>
				<JobLogPage jobId={editingData?.id} />
			</Modal>
		</>
	);
}
